package com.azunitech.intercpt;

public class CircuitBreaker  
{  
    private final int failureThreshold;  
    private int failureCount;  
    private final int timeUntilRetry;  
    private CircuitBreakerStatus status;  
    private long lastOpenedTime;  
    private final String name;  
    private int openCount;  
  
    public CircuitBreaker(String name, int failureThreshold, int timeUntilRetry)  
    {  
        this.name = name;  
        this.failureThreshold = failureThreshold;  
        this.timeUntilRetry = timeUntilRetry;  
        this.status = CircuitBreakerStatus.CLOSED;  
    }  
  
    public String getName()  
    {  
        return name;  
    }  
  
    public void setStatus(final CircuitBreakerStatus status)  
    {  
        this.status = status;  
    }  
  
    public CircuitBreakerStatus getStatus()  
    {  
        return status;  
    }  
  
    public void setLastOpenedTime(final long lastOpenedTime)  
    {  
        this.lastOpenedTime = lastOpenedTime;  
    }  
  
    public long getLastOpenedTime()  
    {  
        return lastOpenedTime;  
    }  
  
    public void addFailure()  
    {  
        failureCount++;  
    }  
  
    private void setFailureCount(final int failureCount)  
    {  
        this.failureCount = failureCount;  
    }  
  
    public int getFailureCount()  
    {  
        return failureCount;  
    }  
  
    public boolean isWaitTimeExceeded()  
    {  
        return System.currentTimeMillis() - timeUntilRetry > lastOpenedTime;  
    }  
  
    public boolean isThresholdReached()  
    {  
        return getFailureCount() >= getFailureThreshold();  
    }  
  
    public int getFailureThreshold()  
    {  
        return failureThreshold;  
    }  
  
    public void open()  
    {  
        setLastOpenedTime(System.currentTimeMillis());  
        setStatus(CircuitBreakerStatus.OPEN);  
        openCount++;  
    }  
  
    public void openHalf()  
    {  
        setStatus(CircuitBreakerStatus.HALF_OPEN);  
    }  
  
    public void close()  
    {  
        setFailureCount(0);  
        setStatus(CircuitBreakerStatus.CLOSED);  
    }  
  
    public boolean isOpen()  
    {  
        return getStatus() == CircuitBreakerStatus.OPEN;  
    }  
  
    public boolean isHalfOpen()  
    {  
        return getStatus() == CircuitBreakerStatus.HALF_OPEN;  
    }  
  
    public boolean isClosed()  
    {  
        return getStatus() == CircuitBreakerStatus.CLOSED;  
    }  
  
    public int getOpenCount()  
    {  
        return openCount;  
    }  
}  